package com.aaa.jvmtest.gcmanagement;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 清除软引用引用的对象后，软引用指向null，而软引用本身也是对象会占用一定内存(少)
 * 如果想要清除软引用对象，可以使用引用队列对象 ReferencesQueue
 *
 * @author Tu
 * @date 2022/7/2 17:18
 */
public class ReferencesQueueTest {

    private static final int _4M = 4 * 1024 * 1024;


    /**
     * 队列符合先进先出的规则
     */
    public static void main(String[] args) {
        List<SoftReference<byte[]>> list = new ArrayList<>();
        //创建引用队列，泛型为引用对象->引用的对象类型
        ReferenceQueue<byte[]> referenceQueue = new ReferenceQueue<>();
        for (int i = 0; i < 5; i++) {
            System.out.println("--第" + (i + 1) + "次循环--");
            //创建软引用对象，并关联引用队列
            //当软引用引用的byte[]对象被回收时，软引用对象就会被加入到引用队列
            SoftReference<byte[]> softReference = new SoftReference<>(new byte[_4M], referenceQueue);
            System.out.println(softReference.get());
            list.add(softReference);
        }
        System.out.println("-------循环结束，剩余个数" + list.size());
        //注意：poll的源码解释：为如果为可用的，删除并返回(这个可用指的是系统可用，对我们来说就是空的无用对象)
        //通过poll方法可以自动将队列中的无用对象删除并返回。这里我们判断删除的是list中的，实际上队列中的已经自动删除
        Reference<? extends byte[]> poll = referenceQueue.poll();
        while (Objects.nonNull(poll)) {
            list.remove(poll);
            poll = referenceQueue.poll();
        }
        System.out.println("-------去除无用引用对象结束，剩余个数" + list.size());
        for (SoftReference<byte[]> softReference : list) {
            //获取软引用引用的对象
            System.out.println(softReference.get());
        }
    }

}
